<template>
  <div class="app-container">
    <!-- 搜索表单 -->
    <div class="search-wrapper">
      <el-form ref="queryFormRef" :model="queryParams" :inline="true">
        <el-form-item label="标题" prop="title">
          <el-input v-model="queryParams.title" placeholder="请输入文章标题" clearable @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="分类" prop="categoryId">
          <el-select v-model="queryParams.categoryId" placeholder="请选择分类" clearable>
            <el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="标签" prop="tagId">
          <el-select v-model="queryParams.tagId" placeholder="请选择标签" clearable>
            <el-option v-for="item in tagOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
            <el-option v-for="item in statusOptions" :key="item.id" :value="item.value" :label="item.label" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 操作按钮区域 -->
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <ButtonGroup>
            <el-button type="primary" icon="Plus" @click="handleAdd" v-permission="['sys:article:add']">新增文章</el-button>
            <el-button type="danger" icon="Delete" :disabled="selectedIds.length === 0"
              v-permission="['sys:article:delete']" @click="handleBatchDelete">批量删除</el-button>
            <el-button type="warning" icon="Setting" v-permission="['sys:article:reptile']"
              @click="reptileDialog.visible = true">爬取文章</el-button>
          </ButtonGroup>
        </div>
      </template>

      <!-- 数据表格 -->
      <el-table v-loading="loading" :data="tableData" style="width: 100%" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="封面" align="center" width="133">
          <template #default="scope">
            <el-image style="width: 120px; height: 80px;border-radius: 10px" :src="scope.row.cover" />
          </template>
        </el-table-column>
        <el-table-column label="标题" align="center" prop="title" width="200" show-overflow-tooltip>
          <template #default="scope">
            <span style="color: var(--el-color-primary);">{{ scope.row.title }}</span>
          </template>
        </el-table-column>
        <el-table-column label="作者" align="center" prop="nickname" show-overflow-tooltip />
        <el-table-column label="分类" align="center" prop="categoryName" />
        <el-table-column label="标签" align="center" width="200">
          <template #default="scope">
            <el-tag v-for="tag in scope.row.tags" :key="tag.id" class="mx-1" size="small">
              {{ tag.name }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="发布状态" align="center" prop="status">
          <template #default="scope">
            <el-switch @change="handleChangeStatus(scope.row)"
              style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" v-model="scope.row.status"
              :active-value="1" :inactive-value="0" />
          </template>
        </el-table-column>
        <el-table-column label="是否推荐" align="center">
          <template #default="{ row }">
            <span v-for="item in yesNoOptions">
              <el-tag :type="item.style" v-if="row.isRecommend === Number(item.value)">
                {{ item.label }}
              </el-tag>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="是否置顶" align="center">
          <template #default="{ row }">
            <span v-for="item in yesNoOptions">
              <el-tag :type="item.style" v-if="row.isStick === Number(item.value)">
                {{ item.label }}
              </el-tag>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="阅读量" align="center" prop="quantity" />
        <el-table-column label="创建时间" align="center" prop="createTime" width="180" />
        <el-table-column label="操作" align="center" width="200" fixed="right">
          <template #default="scope">
            <el-button type="primary" link icon="Edit" @click="handleUpdate(scope.row)"
              v-permission="['sys:article:update']">修改</el-button>
            <el-button type="danger" link icon="Delete" @click="handleDelete(scope.row)"
              v-permission="['sys:article:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页组件 -->
      <div class="pagination-container">
        <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
          :page-sizes="[10, 20, 30, 50]" :total="total" :background="true"
          layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
          @current-change="handleCurrentChange" />
      </div>
    </el-card>

    <!-- 添加或修改对话框 -->
    <el-dialog :title="dialog.title" v-model="dialog.visible" width="1400px" top="3vh" :close-on-click-modal="false">
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="文章标题" prop="title">
          <div class="input-with-ai">
            <el-input v-model="form.title" placeholder="请输入文章标题" />
            <el-button type="primary" icon="MagicStick" class="ai-btn" @click="generateAiContent('title')" :loading="aiLoading.title">AI生成</el-button>
          </div>
        </el-form-item>

        <el-form-item label="文章封面" prop="cover">
          <UploadImage v-model="form.cover" :limit="1" :source="'article-cover'" />
        </el-form-item>

        <el-form-item label="文章简介" prop="summary">
          <div class="input-with-ai">
            <el-input v-model="form.summary" type="textarea" :rows="3" placeholder="请输入文章简介" />
            <el-button type="primary" icon="MagicStick" class="ai-btn" @click="generateAiContent('summary')" :loading="aiLoading.summary">AI生成</el-button>
          </div>
        </el-form-item>

        <el-row :gutter="20" class="mb-20">
          <el-col :span="12">
            <el-form-item label="分类" prop="categoryName">
              <div class="tag-container">
                <div>
                  <el-tag
                    type="success"
                    v-show="form.categoryName"
                    style="margin: 0 1rem 0 0"
                    :closable="true"
                    @close="removeCategory()"
                  >
                    {{ form.categoryName }}
                  </el-tag>
                  <!-- 分类选项 -->
                  <el-popover
                    placement="bottom-start"
                    width="460"
                    trigger="click"
                    v-if="!form.categoryName"
                  >
                    <div class="popover-title">分类</div>
                    <!-- 输入框 -->
                    <el-input
                      style="width: 100%"
                      v-model="categoryName"
                      placeholder="请输入分类名,enter添加自定义分类"
                      @keyup.enter="saveCategory"
                    />
                    <!-- 分类 -->
                    <div class="popover-container">
                      <div>添加分类</div>
                      <el-tag
                        v-for="(item, index) of categoryOptions"
                        :key="index"
                        style="margin-left: 3px; margin-top: 2px"
                        class="category-item"
                        @click="addCategory(item.name)"
                      >
                        {{ item.name }}
                      </el-tag>
                    </div>
                    <template #reference>
                      <el-button type="success" plain> 添加分类 </el-button>
                    </template>
                  </el-popover>
                </div>
                <el-button type="primary" icon="MagicStick" class="ai-btn" @click="generateAiContent('category')" :loading="aiLoading.category">AI推荐</el-button>
              </div>
            </el-form-item>

          </el-col>
          <el-col :span="12">
            <el-form-item label="标签" prop="tags">
              <div class="tag-container">
                <div>
                  <el-tag
                    v-for="(item, index) of form.tags"
                    :key="index"
                    style="margin: 0 1rem 0 0"
                    :closable="true"
                    @close="removeTag(item)"
                  >
                    {{ item }}
                  </el-tag>
                  <!-- 标签选项 -->
                  <el-popover
                    placement="bottom-start"
                    width="460"
                    trigger="click"
                    v-if="form.tags && form.tags.length < 3"
                  >
                    <div class="popover-title">标签</div>
                    <!-- 搜索框 -->
                    <el-input
                      style="width: 100%"
                      v-model="tagName"
                      placeholder="请输入标签名,enter添加自定义标签"
                      @keyup.enter="saveTag"
                    />
                    <!-- 标签 -->
                    <div class="popover-container">
                      <div>添加标签</div>
                      <el-tag
                        v-for="(item, index) of tagOptions"
                        :key="index"
                        style="margin-left: 3px; margin-top: 2px"
                        @click="addTag(item.name)"
                      >
                        {{ item.name }}
                      </el-tag>
                    </div>
                    <template #reference>
                      <el-button type="primary" plain> 添加标签 </el-button>
                    </template>
                  </el-popover>
                </div>
                <el-button type="primary" icon="MagicStick" class="ai-btn" @click="generateAiContent('tags')" :loading="aiLoading.tags">AI推荐</el-button>
              </div>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20" class="mb-20">
          <el-col :span="8">
            <el-form-item label="阅读方式" prop="readType">
              <el-select v-model="form.readType" placeholder="请选择阅读方式">
                <el-option label="免费" :value="1" />
                <el-option label="会员" :value="2" />
                <el-option label="付费" :value="3" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="文章类型" prop="isOriginal">
              <el-select v-model="form.isOriginal" placeholder="请选择文章类型">
                <el-option label="原创" :value="1" />
                <el-option label="转载" :value="0" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="关键词" prop="keywords">
              <el-input v-model="form.keywords" placeholder="请输入关键词" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="转载地址" prop="originalUrl" v-if="form.isOriginal === 0" class="mb-20">
          <el-input v-model="form.originalUrl" placeholder="请输入转载地址" />
        </el-form-item>

        <el-row :gutter="20" class="mb-20">
          <el-col :span="6">
            <el-form-item label="是否置顶" prop="isStick">
              <el-switch style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" v-model="form.isStick"
                :active-value="1" :inactive-value="0" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="是否发布" prop="status">
              <el-select v-model="form.status" placeholder="请选择文章状态">
                <el-option v-for="item in statusOptions" :key="item.id" :value="Number(item.value)"
                  :label="item.label" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="首页轮播" prop="isCarousel">
              <el-switch style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" v-model="form.isCarousel"
                :active-value="1" :inactive-value="0" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="是否推荐" prop="isRecommend">
              <el-switch style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
                v-model="form.isRecommend" :active-value="1" :inactive-value="0" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="文章内容" prop="contentMd" class="mb-20">
          <div class="ai-content-tools">
            <el-button type="primary" icon="MagicStick" @click="generateAiContent('content')" :loading="aiLoading.content">
              AI生成文章内容
            </el-button>
            <el-button type="success" icon="MagicStick" @click="generateAiContent('all')" :loading="aiLoading.all">
              一键生成所有内容
            </el-button>
            
            <!-- AI生成进度条 -->
            <div v-if="aiGenerating" class="ai-progress">
              <div class="progress-status">
                <span>{{ aiCurrentStep }}</span>
                <el-button 
                  type="danger" 
                  size="small" 
                  @click="cancelGeneration" 
                  icon="CircleClose"
                >取消生成</el-button>
              </div>
              <el-progress 
                :percentage="aiProgress" 
                :format="formatRemainingTime" 
                :status="aiProgress < 100 ? '' : 'success'"
              ></el-progress>
            </div>
          </div>
          
          <mavon-editor placeholder="输入文章内容..." style="height: 500px; width: 100%" ref="mdRef" v-model="form.contentMd"
            @imgDel="imgDel" @imgAdd="imgAdd">
            <template #left-toolbar-after>
                  <el-dropdown>
                    <span class="el-dropdown-link">
                      <i title="上传视频"></i>
                      <el-icon class="op-icon fa el-icon-video-camera"
                        ><VideoPlay
                      /></el-icon>
                    </span>
                    <template #dropdown>
                      <el-dropdown-menu>
                        <el-dropdown-item>
                          <el-upload
                            style="display: inline-block"
                            :show-file-list="false"
                            name="filedatas"
                            action=""
                            :http-request="uploadVideo"
                            multiple
                          >
                            <span>上传视频</span>
                          </el-upload>
                        </el-dropdown-item>
                        <el-dropdown-item>
                          <div @click="dialogVisible = true">添加视频地址</div>
                        </el-dropdown-item>
                      </el-dropdown-menu>
                    </template>
                  </el-dropdown>
                </template>
              </mavon-editor>
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button type="primary" :loading="submitLoading" @click="submitForm">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 爬取文章对话框 -->
    <el-dialog title="爬取文章" v-model="reptileDialog.visible" width="800px">
      <el-form ref="reptileFormRef" :model="reptileForm" :rules="rules" label-width="100px">
        <el-form-item label="爬取地址" prop="url">
          <el-input v-model="reptileForm.url" placeholder="请输入爬取地址" />
        </el-form-item>
      </el-form>
      <div style="margin-top: 20px;">
        <el-alert title="暂时只支持Csdn的文章爬取" type="success" :closable="false" />
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button type="primary" :loading="submitLoading" @click="submitReptile">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 添加视频地址对话框 -->
    <el-dialog center title="添加视频" v-model="dialogVisible" width="30%">
      <el-input v-model="videoInput" placeholder="视频地址"></el-input>

      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="addVideo">确 定</el-button>
          <el-button @click="dialogVisible = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ElMessage, ElMessageBox,ElLoading  } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import UploadImage from '@/components/Upload/Image.vue'
import { getCategoryListApi } from '@/api/article/category'
import { getTagListApi } from '@/api/article/tag'
import {
  getArticleListApi, getDetailApi, deleteArticleApi,
  addArticleApi, updateArticleApi, updateStatusApi, reptileArticleApi
} from '@/api/article'
import { uploadApi,deleteFileApi } from '@/api/file'
import { getDictDataByDictTypesApi } from '@/api/system/dict'

// 模拟数据
const categoryOptions = ref<any>([])

const tagOptions = ref<any>([])

// 查询参数
const queryParams = reactive({
  pageNum: 1,
  pageSize: 10,
  title: '',
  categoryId: undefined,
  tagId: undefined,
  status: undefined
})

const loading = ref(false)
const total = ref(0)
const tableData = ref([])
const queryFormRef = ref<FormInstance>()
const formRef = ref<FormInstance>()
const mdRef = ref();
const submitLoading = ref(false)

// AI 相关变量
const aiApiKey = 'sk-vtyikbtifutklfoqyvtztqkiverladsixghbzrqvhembjfbz'
const aiApiUrl = 'https://api.siliconflow.cn/v1/chat/completions'
const aiModel = "deepseek-ai/DeepSeek-R1-0528-Qwen3-8B"
const aiLoading = reactive({
  title: false,
  summary: false,
  category: false,
  tags: false,
  content: false,
  all: false
})
const aiGenerating = ref(false)
const aiProgress = ref(0)
const aiRemainingTime = ref(60) // 初始预计60秒
const aiCurrentStep = ref('准备中...')
const generationTimer = ref<any>(null)
const streamController = ref<AbortController | null>(null)
const generationStartTime = ref(0)
const estimatedTotalTime = ref(60) // 初始预计60秒

// 选中项数组
const selectedIds = ref<string[]>([])

// 弹窗控制
const dialog = reactive({
  title: '',
  visible: false,
  type: 'add'
})

const reptileDialog = reactive({
  visible: false,
})

// 表单数据
const form = reactive<any>({
  id: undefined,
  title: '',
  cover: '',
  summary: '',
  categoryName: '',
  tags: [],
  content: '',
  contentMd: '',
  readType: 1,
  isOriginal: 1,
  originalUrl: '',
  isStick: 0,
  status: 1,
  isCarousel: 0,
  isRecommend: 0,
  keywords: ''
})

const reptileForm = reactive({
  url: ''
})

const statusOptions = ref<any>([])
const yesNoOptions = ref<any>([])

const dialogVisible = ref(false)
const videoInput = ref('')

const tagName = ref('')
const categoryName = ref('')

// 表单校验规则
const rules = reactive<FormRules>({
  title: [
    { required: true, message: '请输入文章标题', trigger: 'blur' },
    { min: 2, max: 100, message: '长度在 2 到 100 个字符', trigger: 'blur' }
  ],
  categoryName: [
    { required: true, message: '请选择文章分类', trigger: 'change' }
  ],
  contentMd: [
    { required: true, message: '请输入文章内容', trigger: 'blur' }
  ],
  summary: [
    { required: true, message: '请输入文章简介', trigger: 'blur' },
    { max: 500, message: '简介最多500个字符', trigger: 'blur' }
  ],
  readType: [
    { required: true, message: '请选择阅读方式', trigger: 'change' }
  ],
  isOriginal: [
    { required: true, message: '请选择文章类型', trigger: 'change' }
  ],
  tags: [
    { required: true, message: '请选择文章标签', trigger: 'change' }
  ],
  originalUrl: [
    {
      required: true,
      message: '请输入转载地址',
      trigger: 'blur',
      validator: (rule: any, value: string, callback: any) => {
        if (form.isOriginal === 0 && !value) {
          callback(new Error('转载文章必须填写转载地址'))
        } else {
          callback()
        }
      }
    }
  ]
})

const removeTag = (tag: string) => {
  form.tags = form.tags.filter((item: string) => item !== tag)
}

const addTag = (tag: any) => {
  if (form.tags.includes(tag)) {
    ElMessage.warning('标签已存在')
    return
  }
  form.tags.push(tag)
}

const saveTag = () => {
  if (tagName.value.trim() !== "") {
    addTag(tagName.value);
    tagName.value = "";
  }
}

const removeCategory = () => {
  form.categoryName = ''
}

const addCategory = (category: any) => {
  if (form.categoryName.includes(category)) {
    ElMessage.warning('分类已存在')
    return
  }
  form.categoryName = category
}

const saveCategory = () => {
  if (categoryName.value.trim() !== "") {
    addCategory(categoryName.value);
    categoryName.value = "";
  }
}

//删除图片
function imgDel(pos: any, $file: any) {
   deleteFileApi(pos[0]).then((res) => {
     ElMessage.success('删除成功')
   })
}
//添加图片
function imgAdd(pos: any, $file: any) {
  var formdata = new FormData();
  formdata.append("file", $file);
  uploadApi(formdata, 'article-content').then((res) => {
    mdRef.value.$img2Url(pos, res.data);
  });
}

// 上传视频
const uploadVideo = (param: any) => {
  const loading = ElLoading.service({
    lock: true,
    text: 'Loading',
    background: 'rgba(0, 0, 0, 0.7)',
  })
  var formData = new FormData();
  formData.append("file", param.file);
  return uploadApi(formData, 'article-content').then((res) => {
    const $vm = mdRef.value;
    $vm.insertText($vm.getTextareaDom(), {
      prefix: `<video height=100% width=100% controls autoplay src="${res.data}"></video>`,
      subfix: "",
      str: "",
    });
    return res;
  }).finally(() => {
    loading.close();
  });
}

/**
 * 添加网络视频地址
 */
 const addVideo = () => {
  // 这里获取到的是mavon编辑器实例，上面挂载着很多方法
  const $vm = mdRef.value;
  // 将文件名与文件路径插入当前光标位置，这是mavon-editor 内置的方法
  $vm.insertText($vm.getTextareaDom(), {
    prefix: `<video height=100% width=100% controls autoplay src="${videoInput.value}"></video>`,
    subfix: "",
    str: "",
  });

  dialogVisible.value = false;
  videoInput.value = "";
}

// 获取分类列表
const getList = async () => {
  loading.value = true
  try {
    const { data } = await getArticleListApi(queryParams)
    tableData.value = data.records
    total.value = data.total
  } catch (error) {
  }
  loading.value = false
}

// 获取状态列表
const getStatusList = async () => {
  const { data } = await getDictDataByDictTypesApi(['article_status', 'sys_yes_no'])
  statusOptions.value = data.article_status.list
  yesNoOptions.value = data.sys_yes_no.list
}

// 表格选择项变化
const handleSelectionChange = (selection: any[]) => {
  selectedIds.value = selection.map(item => item.id)
}

// 爬取文章
const submitReptile = () => {
  if (!reptileForm.url) return
  reptileArticleApi(reptileForm.url).then((res) => {
    ElMessage.success('爬取成功')
    getList()
    reptileDialog.visible = false
    reptileForm.url = ''
  })
}

// 批量删除
const handleBatchDelete = () => {
  if (selectedIds.value.length === 0) return

  ElMessageBox.confirm(`是否确认删除 ${selectedIds.value.length} 篇文章?`, '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      await deleteArticleApi(selectedIds.value)
      ElMessage.success('删除成功')
      selectedIds.value = []
      getList()
    } catch (error) {
    }
  })
}

// 删除
const handleDelete = (row: any) => {
  ElMessageBox.confirm(`是否确认删除 ${row.title} 这篇文章?`, '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      await deleteArticleApi(row.id)
      ElMessage.success('删除成功')
      getList()
    } catch (error) {
    }
  })
}

// 发布文章
const handleChangeStatus = (row: any) => {
  updateStatusApi({ id: row.id, status: row.status }).then((res) => {
    ElMessage.success('修改成功')
    getList()
  })
}

// 搜索
const handleQuery = () => {
  queryParams.pageNum = 1
  getList()
}

// 重置查询
const resetQuery = () => {
  queryFormRef.value?.resetFields()
  handleQuery()
}

//清空表单
const clearForm = () => {
  form.id = undefined
  form.title = ''
  form.cover = undefined
  form.summary = ''
  form.categoryName = ''
  form.tags = []
  form.content = ''
  form.contentMd = ''
  form.originalUrl = ''
  form.isStick = 0
  form.status = 1
  form.isCarousel = 0
  form.isRecommend = 0
  form.keywords = ''
}

// 新增用户
const handleAdd = () => {
  dialog.type = 'add'
  dialog.title = '新增文章'
  dialog.visible = true
  clearForm()
}

// 修改分类
const handleUpdate = (row: any) => {
  clearForm()
  dialog.type = 'edit'
  dialog.title = '修改文章'
  dialog.visible = true
  getDetailApi(row.id).then((res) => {
    Object.assign(form, res.data)
  })
}

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return

  await formRef.value.validate(async (valid) => {
    if (valid) {
      submitLoading.value = true
      form.content = mdRef.value.d_render;
      try {
        if (dialog.type === 'add') {
          await addArticleApi(form)
          ElMessage.success('新增成功')
        } else {
          await updateArticleApi(form)
          ElMessage.success('修改成功')
        }
        getList()
        dialog.visible = false
      } catch (error) {
      } finally {
        submitLoading.value = false
      }
    }
  })
}

// 取消按钮
const cancel = () => {
  dialog.visible = false
  reptileDialog.visible = false
  formRef.value?.resetFields()
  reptileForm.url = ''
}

// 分页大小改变
const handleSizeChange = (val: number) => {
  queryParams.pageSize = val
  getList()
}

// 页码改变
const handleCurrentChange = (val: number) => {
  queryParams.pageNum = val
  getList()
}

// 初始化
onMounted(() => {
  getList()
  getCategoryListApi({ pageNum: 1, pageSize: 1000 }).then((res) => {
    categoryOptions.value = res.data.records
  })
  getTagListApi({ pageNum: 1, pageSize: 1000 }).then((res) => {
    tagOptions.value = res.data.records
  })

  getStatusList()
})

// 图片上传前的处理
const beforeAvatarUpload = (file: File) => {
  // 这里添加文件类型和大小限制
  const isJPG = file.type === 'image/jpeg'
  const isPNG = file.type === 'image/png'
  const isLt2M = file.size / 1024 / 1024 < 2

  if (!isJPG && !isPNG) {
    ElMessage.error('上传头像图片只能是 JPG/PNG 格式!')
    return false
  }
  if (!isLt2M) {
    ElMessage.error('上传头像图片大小不能超过 2MB!')
    return false
  }

  // 模拟上传
  form.cover = URL.createObjectURL(file)
  return false
}

const generateAiContent = async (type: string) => {
  // 设置对应类型的加载状态
  aiLoading[type] = true;
  
  try {
    // 根据类型生成不同的提示词
    let prompt = '';
    let title = form.title || '';
    
    switch (type) {
      case 'title':
        // 如果没有任何内容，提供一些默认主题选择
        if (!form.contentMd && !form.summary) {
          prompt = '请为一篇博客文章生成5个有吸引力的标题，每个标题都要简洁且有吸引力，使用中文，不超过20个字。';
        } else {
          // 根据现有内容生成标题
          prompt = `根据以下内容，生成一个简洁有吸引力的文章标题，使用中文，不超过20个字：\n\n${form.contentMd || form.summary}`;
        }
        
        const titleRes = await callAI(prompt);
        if (titleRes) {
          form.title = extractTitle(titleRes);
          ElMessage.success('标题生成成功！');
        }
        break;
        
      case 'summary':
        // 如果有内容但没有摘要
        if (form.contentMd && !form.summary) {
          prompt = `根据以下文章内容，生成一段简洁的文章摘要，100-200字左右：\n\n${form.contentMd}`;
        } else if (form.title && !form.summary) {
          // 如果只有标题
          prompt = `根据标题"${form.title}"，生成一段吸引人的文章摘要，100-200字左右。`;
        } else {
          // 默认提示
          prompt = `请生成一段博客文章摘要，内容简洁、有吸引力，100-200字左右。`;
        }
        
        const summaryRes = await callAI(prompt);
        if (summaryRes) {
          form.summary = summaryRes.trim().replace(/^['"]|['"]$/g, '').replace(/\n+/g, ' ');
          ElMessage.success('摘要生成成功！');
        }
        break;
        
      case 'category':
        // 根据已有标题和内容推荐分类
        if (categoryOptions.value.length === 0) {
          ElMessage.warning('没有可用的分类数据，请先添加分类');
          break;
        }
        
        const categoryNames = categoryOptions.value.map(c => c.name).join('、');
        
        if (form.title || form.contentMd || form.summary) {
          prompt = `根据以下信息，从这些分类中选择一个最合适的：${categoryNames}\n\n文章标题：${form.title || ''}\n文章摘要：${form.summary || ''}\n文章内容：${form.contentMd ? form.contentMd.substring(0, 200) + '...' : ''}\n\n只需回复一个分类名称，不需要其他解释。`;
        } else {
          ElMessage.warning('请先填写标题或内容，以便AI推荐合适的分类');
          break;
        }
        
        const categoryRes = await callAI(prompt);
        if (categoryRes) {
          const suggestedCategory = categoryRes.trim();
          form.categoryName = suggestedCategory;
          ElMessage.success(`分类推荐成功：${suggestedCategory}`);
        }
        break;
        
      case 'tags':
        // 根据已有标题和内容推荐标签
        if (tagOptions.value.length === 0) {
          ElMessage.warning('没有可用的标签数据，请先添加标签');
          break;
        }
        
        if (form.title || form.contentMd || form.summary) {
          prompt = `根据以下信息，生成2-3个合适的文章标签，每个标签2-4个字，用逗号分隔：\n\n文章标题：${form.title || ''}\n文章分类：${form.categoryName || ''}\n文章摘要：${form.summary || ''}\n文章内容：${form.contentMd ? form.contentMd.substring(0, 200) + '...' : ''}\n\n只需回复标签名称，用逗号分隔，不要有其他解释。`;
        } else {
          ElMessage.warning('请先填写标题或内容，以便AI推荐合适的标签');
          break;
        }
        
        const tagsRes = await callAI(prompt);
        if (tagsRes) {
          // 解析逗号分隔的标签
          const suggestedTags = tagsRes.split(/[,，、]/).map(t => t.trim()).filter(t => t);
          
          // 清空现有标签，并添加推荐的标签（最多3个）
          form.tags = suggestedTags.slice(0, 3);
          ElMessage.success(`标签推荐成功：${form.tags.join('、')}`);
        }
        break;
        
      case 'content':
        // 生成文章内容
        if (!form.title && !form.contentMd) {
          ElMessage.warning('请先提供文章标题或内容主题，以便AI生成相关内容');
          break;
        }
        
        // 组装AI提示
        const basePrompt = `请生成一篇关于"${form.title || '技术博客'}"的详细文章，使用Markdown格式。
文章分类：${form.categoryName || '技术'}
文章标签：${form.tags.join('、') || ''}
文章摘要：${form.summary || ''}

请生成完整的文章内容，包含以下要素：
1. 引言：介绍文章主题和重要性
2. 主体内容：根据主题展开详细讨论，分为3-5个小节
3. 代码示例：如果是技术相关主题，请包含相关代码示例
4. 总结观点

请确保内容专业、有深度并且结构清晰。使用Markdown格式。
`;

        // 创建特殊的指示，要求AI在生成不同部分时发出特定标记
        prompt = `${basePrompt}

重要：在生成内容的过程中，请在每个主要部分之前插入特殊标记，以便我跟踪进度：
- 当你开始写引言时，插入 [STEP:INTRODUCTION]
- 当你开始写第一个主要内容部分时，插入 [STEP:SECTION_1]
- 当你开始写第二个主要内容部分时，插入 [STEP:SECTION_2] 
- 如果有第三个部分，插入 [STEP:SECTION_3]
- 当你开始写代码示例时，插入 [STEP:CODE_EXAMPLES]
- 当你开始写总结时，插入 [STEP:CONCLUSION]

这些标记会在最终内容中被自动删除，请放心使用。`;
        
        // 开始生成内容
        aiGenerating.value = true;
        aiProgress.value = 0;
        aiCurrentStep.value = '准备生成文章...';
        generationStartTime.value = Date.now();
        estimatedTotalTime.value = 120; // 估计2分钟
        
        // 启动进度条更新
        startProgressTimer();
        
        // 清空内容或保留
        if (form.contentMd && confirm('已有文章内容，是否清空重新生成？')) {
          form.contentMd = '';
        }

        // 创建一个变量存储原始内容（如果是在现有内容基础上继续）
        const initialContent = form.contentMd;
        
        // 创建AbortController用于支持取消
        streamController.value = new AbortController();
        
        try {
          // 使用流式响应API获取内容，实时显示
          const response = await fetch(aiApiUrl, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${aiApiKey}`
            },
            body: JSON.stringify({
              model: aiModel,
              messages: [
                {
                  role: "system",
                  content: "你是一位专业的技术文章写作助手，能够使用Markdown格式生成高质量的博客文章内容，并能够根据要求在生成过程中添加特定标记。"
                },
                {
                  role: "user",
                  content: prompt
                }
              ],
              temperature: 0.7,
              max_tokens: 3000,
              stream: true
            }),
            signal: streamController.value.signal
          });
          
          if (!response.ok) {
            throw new Error(`请求失败: ${response.status}`);
          }
          
          // 读取流式响应
          const reader = response.body.getReader();
          const decoder = new TextDecoder("utf-8");
          let buffer = '';
          let generatedContent = '';
          
          // 生成内容的各部分进度权重
          const progressWeights = {
            start: 0,
            introduction: 10,
            section1: 30, 
            section2: 50,
            section3: 70,
            code: 85,
            conclusion: 95,
            end: 100
          };
          
          while (true) {
            const { done, value } = await reader.read();
            
            if (done) {
              break;
            }
            
            // 解码返回的数据
            const chunk = decoder.decode(value, { stream: true });
            buffer += chunk;
            
            // 处理SSE格式的数据
            const lines = buffer.split('\n');
            buffer = lines.pop() || '';
            
            for (const line of lines) {
              if (line.startsWith('data: ')) {
                try {
                  const data = line.substring(5).trim();
                  if (data === '[DONE]') continue;
                  
                  const parsedData = JSON.parse(data);
                  if (parsedData.choices && parsedData.choices.length > 0) {
                    const content = parsedData.choices[0].delta?.content || '';
                    
                    // 检查内容中是否包含步骤标记
                    if (content.includes("[STEP:INTRODUCTION]")) {
                      aiCurrentStep.value = "正在生成引言...";
                      aiProgress.value = progressWeights.introduction;
                    } else if (content.includes("[STEP:SECTION_1]")) {
                      aiCurrentStep.value = "正在生成第一部分内容...";
                      aiProgress.value = progressWeights.section1;
                    } else if (content.includes("[STEP:SECTION_2]")) {
                      aiCurrentStep.value = "正在生成第二部分内容...";
                      aiProgress.value = progressWeights.section2;
                    } else if (content.includes("[STEP:SECTION_3]")) {
                      aiCurrentStep.value = "正在生成第三部分内容...";
                      aiProgress.value = progressWeights.section3;
                    } else if (content.includes("[STEP:CODE_EXAMPLES]")) {
                      aiCurrentStep.value = "正在生成代码示例...";
                      aiProgress.value = progressWeights.code;
                    } else if (content.includes("[STEP:CONCLUSION]")) {
                      aiCurrentStep.value = "正在生成总结...";
                      aiProgress.value = progressWeights.conclusion;
                    }
                    
                    // 累积生成的内容
                    generatedContent += content;
                    
                    // 移除步骤标记，保持内容干净
                    const cleanedContent = generatedContent.replace(/\[STEP:[A-Z_]+\]/g, '');
                    
                    // 更新表单内容
                    form.contentMd = initialContent + cleanedContent;
                  }
                } catch (e) {
                  console.error('解析SSE数据错误', e);
                }
              }
            }
          }
          
          // 完成后清理
          aiCurrentStep.value = "生成完成！";
          aiProgress.value = 100;
          ElMessage.success('文章内容生成成功！');
          
        } catch (error) {
          if (error.name === 'AbortError') {
            ElMessage.info('已取消生成');
          } else {
            console.error('内容生成失败:', error);
            ElMessage.error('生成失败：' + (error.message || '未知错误'));
          }
        } finally {
          clearProgressTimer();
          
          // 添加延迟以确保用户能看到完成状态
          setTimeout(() => {
            aiGenerating.value = false;
            streamController.value = null;
          }, 1000);
        }
        break;
        
      case 'all':
        // 一键生成所有内容
        if (confirm('确定要使用AI一键生成所有内容吗？这将覆盖您已填写的内容。')) {
          // 首先生成标题
          await generateAiContent('title');
          // 然后生成内容
          await generateAiContent('content');
          // 最后生成摘要、分类和标签
          await generateAiContent('summary');
          await generateAiContent('category');
          await generateAiContent('tags');
        }
        break;
    }
  } catch (error) {
    console.error('AI生成内容失败:', error);
    ElMessage.error('AI生成失败：' + (error.message || '未知错误'));
  } finally {
    aiLoading[type] = false;
  }
}

// 从AI回复中提取标题
const extractTitle = (text) => {
  // 去掉引号和标点符号
  return text.trim()
    .replace(/^[""《「【\s]+|[""》」】\s.:：。]+$/g, '')
    .replace(/^\d+\.\s*/, '') // 移除数字编号
    .split('\n')[0] // 取第一行
    .trim();
}

// 基本AI调用
const callAI = async (prompt, isLongContent = false) => {
  try {
    const response = await fetch(aiApiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${aiApiKey}`
      },
      body: JSON.stringify({
        model: aiModel,
        messages: [
          {
            role: "system",
            content: "你是一位专业的技术文章写作助手，能够生成高质量的博客文章内容。"
          },
          {
            role: "user",
            content: prompt
          }
        ],
        temperature: 0.7,
        max_tokens: isLongContent ? 3000 : 1000,
        stream: false
      })
    });

    const data = await response.json();
    
    if (data.choices && data.choices.length > 0 && data.choices[0].message) {
      return data.choices[0].message.content;
    }
    return null;
  } catch (error) {
    console.error('AI API调用失败:', error);
    throw error;
  }
}

// 启动进度条更新定时器
const startProgressTimer = () => {
  clearProgressTimer(); // 先清除可能存在的旧定时器
  
  generationTimer.value = setInterval(() => {
    // 计算经过的时间占总时间的百分比
    const elapsed = (Date.now() - generationStartTime.value) / 1000;
    const progressPercent = Math.min(95, (elapsed / estimatedTotalTime.value) * 100);
    
    // 更新进度
    aiProgress.value = progressPercent;
  }, 1000);
}

// 清除进度条更新定时器
const clearProgressTimer = () => {
  if (generationTimer.value) {
    clearInterval(generationTimer.value);
    generationTimer.value = null;
  }
}

// 格式化剩余时间
const formatRemainingTime = (percentage) => {
  if (percentage >= 100) return '完成';
  
  const remainingSeconds = Math.round((100 - percentage) * estimatedTotalTime.value / 100);
  return `剩余约 ${remainingSeconds} 秒`;
}

const cancelGeneration = () => {
  aiGenerating.value = false;
  aiProgress.value = 0;
  aiCurrentStep.value = '生成已取消';
  clearProgressTimer();
}
</script>

<style lang="scss" scoped>
.avatar-uploader {
  :deep(.el-upload) {
    border: 2px dashed var(--el-border-color-lighter);
    border-radius: 8px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);

    &:hover {
      border-color: var(--el-color-primary);
      background-color: var(--el-color-primary-light-9);
    }
  }

  .avatar-uploader-icon {
    font-size: 28px;
    color: var(--el-text-color-secondary);
    width: 120px;
    height: 120px;
    text-align: center;
    line-height: 120px;
  }

  .avatar {
    width: 120px !important;
    height: 120px !important;
  }
}

.app-container {

  .pagination-container {
    display: flex;
    justify-content: center;
    margin-top: 20px;
  }

  :deep(.el-dialog) {
    .el-dialog__body {
      padding: 20px 40px;
    }

    .el-form {
      .el-form-item {
        margin-bottom: 22px;

        &:last-child {
          margin-bottom: 0;
        }

        .el-form-item__label {
          font-weight: 500;
          padding-right: 20px;
        }
      }

      .el-select {
        width: 100%;
      }
    }

    .v-note-wrapper {
      z-index: 1;
      min-height: 500px;
      margin-bottom: 20px;
    }
  }

  .mb-20 {
    margin-bottom: 20px;
  }

  .input-with-ai {
    display: flex;
    align-items: center;
    
    .el-input {
      flex: 1;
    }
    
    .ai-btn {
      margin-left: 10px;
      white-space: nowrap;
    }
  }

  .dialog-footer {
    text-align: right;
    padding-top: 20px;
    border-top: 1px solid var(--el-border-color-lighter);

    .el-button {
      padding: 12px 25px;

      &+.el-button {
        margin-left: 12px;
      }
    }
  }

  .el-tag {
    margin-right: 8px;
    margin-bottom: 8px;
  }
  
  .tag-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    
    > div:first-child {
      flex: 1;
    }
    
    .ai-btn {
      margin-left: 10px;
    }
  }
  
  .ai-content-tools {
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    
    .ai-progress {
      flex: 1;
      margin-left: 15px;
      min-width: 200px;
      
      .progress-status {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 6px;
        
        span {
          font-size: 14px;
          font-weight: 500;
          color: #606266;
        }
      }
    }
  }
}

:root[data-theme='dark'] {
  .app-container {
    :deep(.el-dialog) {
      .el-form {
        .el-input__wrapper {
          box-shadow: 0 0 0 1px var(--el-border-color) inset;
        }
      }
    }
  }
}
</style>